package com.irdstudio.efp.flow.service.impl;

import static com.irdstudio.basic.sequence.service.DefaultPatternDescriptor.DAY;
import static com.irdstudio.basic.sequence.service.DefaultPatternDescriptor.MONTH;
import static com.irdstudio.basic.sequence.service.DefaultPatternDescriptor.SEQ;
import static com.irdstudio.basic.sequence.service.DefaultPatternDescriptor.YEAR_4;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.irdstudio.basic.sequence.service.DefaultPatternDescriptor;
import com.irdstudio.basic.sequence.service.PatternDescriptor;
import com.irdstudio.basic.sequence.service.facade.PatternedLimitableSeqService;
import com.irdstudio.efp.flow.common.constance.FlowConstance;
import com.irdstudio.efp.flow.service.dao.BizEventInfoDao;
import com.irdstudio.efp.flow.service.dao.BizFlowInfoDao;
import com.irdstudio.efp.flow.service.dao.BizFlowNodeDao;
import com.irdstudio.efp.flow.service.dao.BizFlowProcessDao;
import com.irdstudio.efp.flow.service.dao.BizFlowRouteDao;
import com.irdstudio.efp.flow.service.dao.BizFlowTaskDao;
import com.irdstudio.efp.flow.service.dao.BizFlowTaskParamDao;
import com.irdstudio.efp.flow.service.dao.BizStageInfoDao;
import com.irdstudio.efp.flow.service.domain.BizEventInfo;
import com.irdstudio.efp.flow.service.domain.BizFlowInfo;
import com.irdstudio.efp.flow.service.domain.BizFlowNode;
import com.irdstudio.efp.flow.service.domain.BizFlowProcess;
import com.irdstudio.efp.flow.service.domain.BizFlowTask;
import com.irdstudio.efp.flow.service.domain.BizStageInfo;
import com.irdstudio.efp.flow.service.facade.BizFlowInfoService;
import com.irdstudio.efp.flow.service.vo.BizEventInfoVO;
import com.irdstudio.efp.flow.service.vo.BizFlowCfgTreeVO;
import com.irdstudio.efp.flow.service.vo.BizFlowInfoVO;
import com.irdstudio.efp.flow.service.vo.BizFlowNodeVO;
import com.irdstudio.efp.flow.service.vo.BizStageInfoVO;
import com.irdstudio.basic.framework.core.base.AbstractFrameworkService;
import com.irdstudio.basic.framework.core.base.FrameworkService;
import com.irdstudio.basic.framework.core.constant.SequenceConstance;
/**
 * <p>ServiceImpl: 业务流转信息				<p>
 * @author ligm
 * @date 2018-05-05
 */
@Service("bizFlowInfoService")
public class BizFlowInfoServiceImpl extends AbstractFrameworkService implements BizFlowInfoService, FrameworkService {
	
	private static Logger logger = LoggerFactory.getLogger(BizFlowInfoServiceImpl.class);

	@Autowired
	private BizFlowInfoDao bizFlowInfoDao;
	@Autowired
	private BizStageInfoDao bizStageInfoDao;
	
	@Autowired
	private BizFlowNodeDao bizFlowNodeDao;
	
	@Autowired
	private BizEventInfoDao bizEventInfoDao;
	
	@Autowired
	private BizFlowProcessDao bizFlowProcessDao;
	
	@Autowired
	private BizFlowRouteDao bizFlowRouteDao;
	
	@Autowired
	private BizFlowTaskDao bizFlowTaskDao;
	
	@Autowired
	private BizFlowTaskParamDao bizFlowTaskParamDao;
	
	@Autowired
	private PatternedLimitableSeqService sequenceService;
	
	public static final PatternDescriptor PATTERN = 
			DefaultPatternDescriptor.of("FW" + YEAR_4 + MONTH + DAY + SEQ, 9);
	/**
	 * 新增操作
	 */
	public int insertBizFlowInfo(BizFlowInfoVO inBizFlowInfoVo) {
		logger.debug("当前新增数据为:"+ inBizFlowInfoVo.toString());
		int num = 0;
		try {
			BizFlowInfo bizFlowInfo = new BizFlowInfo();
			setInsertDefaultProperty(inBizFlowInfoVo);
			inBizFlowInfoVo.setBizFlowId
			(sequenceService.getPatternedSequence(SequenceConstance.BIZ_FLOW_SEQ_ID, PATTERN));
			beanCopy(inBizFlowInfoVo, bizFlowInfo);
			
			num = bizFlowInfoDao.insertBizFlowInfo(bizFlowInfo);
		} catch (Exception e) {
			logger.error("新增数据发生异常!", e);
			num = -1;
		}
		logger.debug("当前新增数据条数为:"+ num);
		return num;
	}

	/**
	 * 删除操作
	 */
	public int deleteByPk(BizFlowInfoVO inBizFlowInfoVo) {
		logger.debug("当前删除数据条件为:"+ inBizFlowInfoVo);
		int num = 0;
		int ret = 0;
		try {
			BizFlowInfo bizFlowInfo = new BizFlowInfo();
			beanCopy(inBizFlowInfoVo, bizFlowInfo);
			ret = num = bizFlowInfoDao.deleteByPk(bizFlowInfo);
			String bizFlowId = inBizFlowInfoVo.getBizFlowId();//流转ID
			//删除节点
			num = bizFlowNodeDao.deleteByBizFlowId(bizFlowId);
			logger.debug("根据条件:"+ inBizFlowInfoVo +"删除的节点数据条数为"+ num);
			//删除任务
			num = bizFlowTaskDao.deleteByBizFlowId(bizFlowId);
			logger.debug("根据条件:"+ inBizFlowInfoVo +"删除的任务数据条数为"+ num);
			//删除任务参数
			BizFlowNodeVO bizFlowNode = new BizFlowNodeVO();
			bizFlowNode.setBizFlowId(bizFlowId);
			List<BizFlowNode> nodeList = bizFlowNodeDao.queryAllByFlowId(bizFlowNode);
			if(nodeList != null) {
				for(int i=0; i<nodeList.size(); i++) {
					BizFlowNode vo = nodeList.get(i);
					List<BizFlowTask> taskList = bizFlowTaskDao.queryByBizNodeId(vo.getBizNodeId());
					for(int j=0; j<taskList.size(); j++) {
						BizFlowTask bizFlowTask = taskList.get(j);
						bizFlowTaskParamDao.deleteByTaskId(bizFlowTask.getTaskId());
					}
				}
			}
			//删除子表数据：业务流转过程配置biz_flow_process
			BizFlowProcess bizFlowProcess = new BizFlowProcess();
			bizFlowProcess.setBizFlowId(bizFlowId);
			num = bizFlowProcessDao.deleteByBizFlowID(bizFlowProcess);
			logger.debug("根据条件:"+ inBizFlowInfoVo +"删除的事件数据条数为"+ num);
			//删除子表数据：业务流转路由信息biz_flow_route
			num = bizFlowRouteDao.deleteByBizFlowId(bizFlowId);
			logger.debug("根据条件:"+ inBizFlowInfoVo +"删除的路由数据条数为"+ num);
		} catch (Exception e) {
			logger.error("删除数据发生异常!", e);
			ret = -1;
		}
		return ret;
	}


	/**
	 * 更新操作
	 */
	public int updateByPk(BizFlowInfoVO inBizFlowInfoVo) {
		logger.debug("当前修改数据为:"+ inBizFlowInfoVo.toString());
		int num = 0;
		try {
			setUpdateDefaultProperty(inBizFlowInfoVo);
			BizFlowInfo bizFlowInfo = new BizFlowInfo();
			beanCopy(inBizFlowInfoVo, bizFlowInfo);
			num = bizFlowInfoDao.updateByPk(bizFlowInfo);
		} catch (Exception e) {
			logger.error("修改数据发生异常!", e);
			num = -1;
		}
		logger.debug("根据条件:"+ inBizFlowInfoVo +"修改的数据条数为"+ num);
		return num;
	}
	
	/**
	 * 查询操作
	 */
	public BizFlowInfoVO queryByPk(BizFlowInfoVO inBizFlowInfoVo) {
		
		logger.debug("当前查询参数信息为:"+ inBizFlowInfoVo);
		try {
			BizFlowInfo queryBizFlowInfo = new BizFlowInfo();
			beanCopy(inBizFlowInfoVo, queryBizFlowInfo);
			BizFlowInfo queryRslBizFlowInfo = bizFlowInfoDao.queryByPk(queryBizFlowInfo);
			if (Objects.nonNull(queryRslBizFlowInfo)) {
				BizFlowInfoVO outBizFlowInfoVo = beanCopy(queryRslBizFlowInfo, new BizFlowInfoVO());
				logger.debug("当前查询结果为:"+ outBizFlowInfoVo.toString());
				return outBizFlowInfoVo;
			} else {
				logger.debug("当前查询结果为空!");
			}
		} catch (Exception e) {
			logger.error("查询数据发生异常!", e);
		}
		return null;
	}


	/**
	 * 查询用户权限数据
	 */
	@SuppressWarnings("unchecked")
	public List<BizFlowInfoVO> queryAllOwner(BizFlowInfoVO bizFlowInfoVo) {

		logger.debug("当前查询本人所属数据信息的参数信息为:");
		List<BizFlowInfoVO> list = null;
		try {
			List<BizFlowInfo> bizFlowInfos = bizFlowInfoDao.queryAllOwnerByPage(bizFlowInfoVo);
			logger.debug("当前查询本人所属数据信息的结果集数量为:"+ bizFlowInfos.size());
			pageSet(bizFlowInfos, bizFlowInfoVo);
			list = (List<BizFlowInfoVO>) beansCopy(bizFlowInfos, BizFlowInfoVO.class);
		} catch (Exception e) {
			logger.error("数据转换出现异常!", e);
		}
		
		return list;
	
	}


	/**
	 * 查询当前机构权限数据
	 */
	@SuppressWarnings("unchecked")
	public List<BizFlowInfoVO> queryAllCurrOrg(BizFlowInfoVO bizFlowInfoVo) {

		logger.debug("当前查询本人所属机构数据信息的参数信息为:");
		List<BizFlowInfo> bizFlowInfos = bizFlowInfoDao.queryAllCurrOrgByPage(bizFlowInfoVo);
		logger.debug("当前查询本人所属机构数据信息的结果集数量为:"+bizFlowInfos.size());
		List<BizFlowInfoVO> list = null;
		try {
			pageSet(bizFlowInfos, bizFlowInfoVo);
			list = (List<BizFlowInfoVO>) beansCopy(bizFlowInfos, BizFlowInfoVO.class);
		} catch (Exception e) {
			logger.error("数据转换出现异常!", e);
		}
		
		return list;
	
	}


	/**
	 * 查询当前机构及下属机构权限数据
	 */
	@SuppressWarnings("unchecked")
	public List<BizFlowInfoVO> queryAllCurrDownOrg(BizFlowInfoVO bizFlowInfoVo) {

		logger.debug("当前查询本人所属机构及以下数据信息的参数信息为:");
		List<BizFlowInfo> bizFlowInfos = bizFlowInfoDao.queryAllCurrDownOrgByPage(bizFlowInfoVo);
		logger.debug("当前查询本人所属机构及以下数据信息的结果集数量为:"+ bizFlowInfos.size());
		List<BizFlowInfoVO> list = null;
		try {
			pageSet(bizFlowInfos, bizFlowInfoVo);
			list = (List<BizFlowInfoVO>) beansCopy(bizFlowInfos, BizFlowInfoVO.class);
		} catch (Exception e) {
			logger.error("数据转换出现异常!", e);
		}
		
		return list;
	
	}

	/**
	 * 查询业务流转配置树
	 */
	@Override
	public List<BizFlowCfgTreeVO<?>> queryBizFlowCfgTree(BizFlowInfoVO bizFlowInfoVo) {
		List<BizFlowCfgTreeVO<?>> bizFlowCfgTreeList = null;
		try {
			bizFlowCfgTreeList = new ArrayList<>();
			
			//查询业务流转配置信息作为根节点信息
			BizFlowInfo flowParam = new BizFlowInfo();
			beanCopy(bizFlowInfoVo, flowParam);
			BizFlowInfo bizFlowInfo = bizFlowInfoDao.queryByPk(flowParam);
			//转成业务VO
			BizFlowInfoVO flowVO = new BizFlowInfoVO();
			beanCopy(bizFlowInfo, flowVO);
			//放入treeVo中提供到前端使用
			BizFlowCfgTreeVO<BizFlowInfoVO> root = new BizFlowCfgTreeVO<>();
			root.setNodeId(flowVO.getBizFlowId());
			//root.setNodeName(flowVO.getBizFlowName());
			root.setNodeName("业务周期");
			root.setParentNodeId(flowVO.getBizFlowId());
			//设置节点类型为: 业务流转配置
			root.setNodeType(FlowConstance.BIZ_CFG_TREE_NODE_TYPE_FLOW);
			root.setBizFlowId(flowVO.getBizFlowId());
			root.setBizFlowName(flowVO.getBizFlowName());
			root.setData(flowVO);
			bizFlowCfgTreeList.add(root);
			
			//查询业务阶段信息
			BizStageInfo paramStage = new BizStageInfo();
			paramStage.setBizFlowType(flowVO.getBizFlowType());
			List<BizStageInfo> stageInfoList = bizStageInfoDao.queryAllInfo(paramStage);
			if(stageInfoList != null && stageInfoList.size() > 0) {
				for(int i=0; i<stageInfoList.size(); i++) {
					BizStageInfoVO stageVO = new BizStageInfoVO();
					beanCopy(stageInfoList.get(i), stageVO);
					
					//将阶段信息装入树中
					BizFlowCfgTreeVO<BizStageInfoVO> vo = new BizFlowCfgTreeVO<>();
					vo.setNodeId(stageVO.getBizStageId());
					vo.setNodeName(stageVO.getBizStageName());
					vo.setParentNodeId(flowVO.getBizFlowId());
					//设置节点类型为: 业务阶段
					vo.setNodeType(FlowConstance.BIZ_CFG_TREE_NODE_TYPE_STAGE);
					vo.setBizFlowId(flowVO.getBizFlowId());
					vo.setBizFlowName(flowVO.getBizFlowName());
					vo.setData(stageVO);
					bizFlowCfgTreeList.add(vo);
					
					//查询阶段下的节点信息
					BizFlowNodeVO nodeParam = new BizFlowNodeVO();
					nodeParam.setBizStageId(stageVO.getBizStageId());
					nodeParam.setBizFlowId(flowVO.getBizFlowId());
					List<BizFlowNode> nodeInfoList = bizFlowNodeDao.queryAllByFlowIdAndStageId(nodeParam);
					for(int j=0; j<nodeInfoList.size(); j++) {
						BizFlowNodeVO nodeVO = new BizFlowNodeVO();
						beanCopy(nodeInfoList.get(j), nodeVO);
						
						//将节点信息装入树中
						BizFlowCfgTreeVO<BizFlowNodeVO> nodeTreeVO = new BizFlowCfgTreeVO<>();
						nodeTreeVO.setNodeId(nodeVO.getBizNodeId());
						nodeTreeVO.setNodeName(nodeVO.getBizNodeName());
						nodeTreeVO.setParentNodeId(nodeVO.getBizStageId());
						//设置节点类型为: 业务流转节点
						nodeTreeVO.setNodeType(FlowConstance.BIZ_CFG_TREE_NODE_TYPE_NODE);
						nodeTreeVO.setBizFlowId(flowVO.getBizFlowId());
						nodeTreeVO.setBizFlowName(flowVO.getBizFlowName());
						nodeTreeVO.setData(nodeVO);
						bizFlowCfgTreeList.add(nodeTreeVO);
					}
				}
			}
			
		} catch (Exception e) {
			logger.error("查询业务流转配置树出现异常!", e);
		}
		
		return bizFlowCfgTreeList;
	}
	
	public List<BizFlowCfgTreeVO<?>> queryBizFlowEventCfgTree(BizFlowInfoVO bizFlowInfoVo) {
		List<BizFlowCfgTreeVO<?>> bizFlowCfgTreeList = null;
		try {
			bizFlowCfgTreeList = new ArrayList<>();
			
			//查询业务流转配置信息作为根节点信息
			BizFlowInfo flowParam = new BizFlowInfo();
			beanCopy(bizFlowInfoVo, flowParam);
			BizFlowInfo bizFlowInfo = bizFlowInfoDao.queryByPk(flowParam);
			//转成业务VO
			BizFlowInfoVO flowVO = new BizFlowInfoVO();
			beanCopy(bizFlowInfo, flowVO);
			//放入treeVo中提供到前端使用
			BizFlowCfgTreeVO<BizFlowInfoVO> root = new BizFlowCfgTreeVO<>();
			root.setNodeId(flowVO.getBizFlowId());
			//root.setNodeName(flowVO.getBizFlowName());
			root.setNodeName("业务事件");
			root.setParentNodeId(flowVO.getBizFlowId());
			//设置节点类型为: 业务流转配置
			root.setNodeType(FlowConstance.BIZ_CFG_TREE_NODE_TYPE_FLOW);
			root.setBizFlowId(flowVO.getBizFlowId());
			root.setBizFlowName(flowVO.getBizFlowName());
			root.setData(flowVO);
			bizFlowCfgTreeList.add(root);
			
			//查询事件配置
			BizEventInfo eventInfo = new BizEventInfo();
			eventInfo.setBizFlowType(flowVO.getBizFlowType());
			List<BizEventInfo> eventInfoList = bizEventInfoDao.queryAllByFlowType(eventInfo);
			if(eventInfoList != null && eventInfoList.size() > 0) {
				for(int i=0; i<eventInfoList.size(); i++) {
					BizEventInfoVO eventVO = new BizEventInfoVO();
					beanCopy(eventInfoList.get(i), eventVO);
					
					//将事件信息装入树中
					BizFlowCfgTreeVO<BizEventInfoVO> eventTreeVO = new BizFlowCfgTreeVO<>();
					eventTreeVO.setNodeId(eventVO.getBizEventId());
					eventTreeVO.setNodeName(eventVO.getBizEventName());
					eventTreeVO.setParentNodeId(flowVO.getBizFlowId());
					//设置节点类型为: 业务流转节点
					eventTreeVO.setNodeType(FlowConstance.BIZ_CFG_TREE_NODE_TYPE_EVENT);
					eventTreeVO.setBizFlowId(flowVO.getBizFlowId());
					eventTreeVO.setBizFlowName(flowVO.getBizFlowName());
					eventTreeVO.setData(eventVO);
					bizFlowCfgTreeList.add(eventTreeVO);
				}
			}
			
		} catch (Exception e) {
			logger.error("查询业务流转事件配置树出现异常!", e);
		}
		
		return bizFlowCfgTreeList;
	}
	
	/**
	 * 根据业务流转类型、法人机构获取业务流转信息
	 */
	@SuppressWarnings("unchecked")
	public List<BizFlowInfoVO> queryBizFlowInfoByFlowType(BizFlowInfoVO bizFlowInfoVo) {

		logger.debug("当前查询本人所属机构及以下数据信息的参数信息为:" + bizFlowInfoVo);
		List<BizFlowInfo> bizFlowInfos = bizFlowInfoDao.queryBizFlowInfoByFlowType(bizFlowInfoVo);
		logger.debug("当前查询本人所属机构及以下数据信息的结果集数量为:"+ bizFlowInfos.size());
		List<BizFlowInfoVO> list = null;
		try {
			list = (List<BizFlowInfoVO>) beansCopy(bizFlowInfos, BizFlowInfoVO.class);
		} catch (Exception e) {
			logger.error("数据转换出现异常!", e);
		}
		
		return list;
	
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<BizFlowInfoVO> queryBizFlowByCondition(BizFlowInfoVO bizFlowInfoVO) {
		logger.info("queryBizFlowByCondition开始查询");
		List<BizFlowInfo> bizFlowInfos = bizFlowInfoDao.queryBizFlowByConditionByPage(bizFlowInfoVO);
		List<BizFlowInfoVO> list = null;
		try {
			pageSet(bizFlowInfos, bizFlowInfoVO);
			list = (List<BizFlowInfoVO>) beansCopy(bizFlowInfos, BizFlowInfoVO.class);
		} catch (Exception e) {
			logger.error("数据转换出现异常!", e);
		}
		return list;
	}

}
